package com.hwd.gmall.list.service.impl;

import com.hwd.gmall.common.constant.RedisConst;
import com.hwd.gmall.list.dao.GoodsDao;
import com.hwd.gmall.list.service.GoodsService;
import com.hwd.gmall.model.list.Goods;
import com.hwd.gmall.model.list.SearchAttr;
import com.hwd.gmall.model.product.BaseAttrInfo;
import com.hwd.gmall.model.product.BaseCategoryView;
import com.hwd.gmall.model.product.BaseTrademark;
import com.hwd.gmall.model.product.SkuInfo;
import com.hwd.gmall.product.feign.ProductFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;


/**
 * @author 黄伟东/Victor
 * @date 2022/4/27 16:00
 */
@Service
public class GoodsServiceImpl implements GoodsService {

    @Resource
    private GoodsDao goodsDao;

    @Autowired
    private ProductFeignClient productFeignClient;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 将商品数据写入es中
     *
     * @param skuId skuInfo商品表的id
     */
    @Override
    public void saveSkuIntoEs(Long skuId) {

        // 参数校验
        if (skuId == null) {
            return;
        }

        // 调用productFeignClient远程feign接口，查询商品对象需要的所有属性
        SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);

        // 判断是否存在该skuId的商品
        if (skuInfo == null || skuInfo.getId() == null) {
            return;
        }

        // 商品对象初始化
        Goods goods = new Goods();

        // 设置基本信息
        goods.setId(skuInfo.getId());
        goods.setDefaultImg(skuInfo.getSkuDefaultImg());
        goods.setTitle(skuInfo.getSkuName());
        goods.setPrice(skuInfo.getPrice().doubleValue());
        goods.setCreateTime(new Date());

        // 设置品牌信息
        BaseTrademark baseTrademark = productFeignClient.getBaseTrademark(skuInfo.getTmId());
        goods.setTmId(baseTrademark.getId());
        goods.setTmName(baseTrademark.getTmName());
        goods.setTmLogoUrl(baseTrademark.getLogoUrl());

        // 设置分类信息
        BaseCategoryView category = productFeignClient.getCategory(skuInfo.getCategory3Id());
        goods.setCategory1Id(category.getCategory1Id());
        goods.setCategory1Name(category.getCategory1Name());
        goods.setCategory2Id(category.getCategory2Id());
        goods.setCategory2Name(category.getCategory2Name());
        goods.setCategory3Id(category.getCategory3Id());
        goods.setCategory3Name(category.getCategory3Name());

        // 设置平台属性信息
        List<BaseAttrInfo> baseAttrInfoList = productFeignClient.getBaseAttrInfo(skuId);
        List<SearchAttr> attrs = baseAttrInfoList.stream().map(baseAttrInfo -> {
            SearchAttr searchAttr = new SearchAttr();
            searchAttr.setAttrId(baseAttrInfo.getId());
            searchAttr.setAttrName(baseAttrInfo.getAttrName());
            searchAttr.setAttrValue(baseAttrInfo.getAttrValueList().get(0).getValueName());
            return searchAttr;
        }).collect(Collectors.toList());
        goods.setAttrs(attrs);

        // 把商品对象保存到es中
        goodsDao.save(goods);
    }

    /**
     * 将商品从es中移除
     *
     * @param goodsId 商品id
     */
    @Override
    public void removeGoodsFromEs(Long goodsId) {
        goodsDao.deleteById(goodsId);
    }

    /**
     * 给指定商品添加热度值
     *
     * @param goodsId 商品id
     * @return boolean
     */
    @Override
    public boolean addScore(Long goodsId) {
        // 参数校验
        if (goodsId == null) {
            return true;
        }

        // 去redis中进行热度值+操作，increment初始值为0
        Double score = redisTemplate.opsForZSet().incrementScore("goods_hot_score", goodsId + "", 1);
        if (score != null && score % RedisConst.HOT_SCORE_UPDATE_RATE == 0) {
            // 去es中查询商品
            Optional<Goods> goodsOptional = goodsDao.findById(goodsId);
            if (!goodsOptional.isPresent()) {
                return true;
            }

            // 获取商品当前的热度值
            Goods goods = goodsOptional.get();
            goods.setHotScore(score.longValue());

            // 更新商品的数据
            goodsDao.save(goods);
        }

        return true;
    }
}
